<xsl:stylesheet version="1.0"
xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx"
                xmlns:edm="http://schemas.microsoft.com/ado/2009/11/edm"
xmlns:ssdl="http://schemas.microsoft.com/ado/2009/11/edm/ssdl"
                exclude-result-prefixes="edmx ssdl edm"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="/edmx:Edmx/edmx:Runtime">
    <xsl:for-each select="edmx:ConceptualModels/edm:Schema/edm:EntityType" >
    <xsl:variable name="EntityTypeName" select="@Name" />
      <xsl:variable name="EntitySet" select="/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema/edm:EntityContainer/edm:EntitySet[substring-after(@EntityType, '.') = $EntityTypeName]" />
      <xsl:variable name="EntitySetName" select="$EntitySet/@Name" />
      function <xsl:value-of select="$EntityTypeName"/>ViewModel() {
      var self = this;
      self.entities = ko.observableArray();
      self.selectedEntity = ko.observable(); // Nothing selected by default
      self.selectedEntity.extend({ notify: 'always' });

      <xsl:for-each select="edm:NavigationProperty" >
          <!-- Relationship -> (Association)AssociationSet(Name) -> (Name)Association -> EndType(Role) = (ToRole)NavigationProperty -->
          <xsl:variable name="ToRole" select="@ToRole" />
          <xsl:variable name="ToRolePrefix" select="substring-before(@ToRole, '_')" />
        <xsl:variable name="Relationship" select="@Relationship" />
        <xsl:variable name="AssociationSet" select="/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema/edm:EntityContainer/edm:AssociationSet[@Association = $Relationship]" />
        <xsl:variable name="Association" select="/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema/edm:Association[@Name = $AssociationSet/@Name]" />
        <xsl:variable name="ConstraintPrincipal" select="$Association/edm:ReferentialConstraint/edm:Principal" />
        <xsl:variable name="ConstraintDependent" select="$Association/edm:ReferentialConstraint/edm:Dependent" />
        <xsl:variable name="AssociationSetEnd" select="$AssociationSet/edm:End[@Role = $ToRole]" />
        <xsl:variable name="End" select="$Association/edm:End[@Role = $ToRole]" />
        <xsl:variable name="Multiplicity" select="$End/@Multiplicity" />
        <xsl:variable name="EndType" select="substring-after($End/@Type, '.')" />
        <xsl:variable name="EndEntitySetName" select="$AssociationSetEnd/@EntitySet" />
        <xsl:variable name="IsKey" select="string-length(substring-before(@Relationship, 'LK_')) > 0" />
        <xsl:if test="$Multiplicity != '*'" >
          <xsl:if test="$IsKey = 'True'">
            if (window.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$EndType"/> == null)
            {
            self.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$ToRole"/> = new <xsl:value-of select="$EndType"/>ViewModel();
            // todo : change to lazy load these collections
            self.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$ToRole"/>.apiController.getList();
            window.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$EndType"/> = self.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$ToRole"/>;
            }
            else
            {
            self.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$ToRole"/> = window.<xsl:if test="$ToRolePrefix != 'LK'">LK_</xsl:if><xsl:value-of select="$EndType"/>;
            }
          </xsl:if>
        </xsl:if>
        <xsl:if test="$Multiplicity = '*'" >
          self.select<xsl:value-of select="@Name"/> = function (entity) {
          if (entity != null) {
          self.vm<xsl:value-of select="@Name"/>.apiController.selectEntity(entity);
          }
          }

          self.loadTemplate<xsl:value-of select="@Name"/> = function (successFunction) {
          self.initvm<xsl:value-of select="@Name"/>();
          self.vm<xsl:value-of select="@Name"/>.apiController.loadTemplate(successFunction);
          
          }

          self.initvm<xsl:value-of select="@Name"/> = function () {
          if (self.vm<xsl:value-of select="@Name"/> == null) {
          self.vm<xsl:value-of select="@Name"/> = new <xsl:value-of select="$EndType"/>ViewModel();
          }
          }

          self.<xsl:value-of select="@Name"/> = function (viewModel) {
          viewModel.initvm<xsl:value-of select="@Name"/>();
          viewModel.lazy<xsl:value-of select="@Name"/> = ko.observableArray(viewModel.selectedEntity().<xsl:value-of select="@Name"/>());
          viewModel.vm<xsl:value-of select="@Name"/>.entities = viewModel.lazy<xsl:value-of select="@Name"/>;

          viewModel.lastSelectedEntity = viewModel.selectedEntity;
          return viewModel.lazy<xsl:value-of select="@Name"/>;
          }
 
          self.add<xsl:value-of select="@Name"/> = function (entity) {
          self.initvm<xsl:value-of select="@Name"/>();
          self.vm<xsl:value-of select="@Name"/>.entities = self.lazy<xsl:value-of select="@Name"/>;
          self.vm<xsl:value-of select="@Name"/>.apiController.addEntity(self.afterAdd<xsl:value-of select="@Name"/>, self.vm<xsl:value-of select="@Name"/>);
          }
          self.afterAdd<xsl:value-of select="@Name"/> = function (vm<xsl:value-of select="@Name"/>, entity) {
          <xsl:if test="$ConstraintDependent/edm:PropertyRef/@Name != ''">
            entity().<xsl:value-of select="$ConstraintDependent/edm:PropertyRef/@Name"/>(self.selectedEntity().<xsl:value-of select="$ConstraintPrincipal/edm:PropertyRef/@Name"/>);
          </xsl:if>
          }
        </xsl:if>

      </xsl:for-each>
      self.apiController = new ApiController(this, "<xsl:value-of select="$EntityTypeName"/>");
      }
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
